package cn.fl.prjsteprebate.service.impl;

import cmm.comm.facade.framework.api.ISysDictionaryApiService;
import cmm.comm.facade.framework.dto.SysDictionaryDTO;
import cmm.mid.core.framework.dto.DataResultDTO;
import cmm.mid.core.framework.page.DataResultVO;
import cmm.mid.core.framework.page.Pager;
import cmm.user.facade.system.api.ISysOrgApiService;
import cmm.user.facade.system.condition.SysOrgQueryCondition;
import cmm.user.facade.system.dto.SysOrgDTO;
import cn.cmm.base.framework.constant.BaseExceptionConstant;
import cn.cmm.base.framework.exception.BaseException;
import cn.cmm.base.framework.utils.BaseLogUtils;
import cn.cmm.base.framework.utils.CollectionUtils;
import cn.cmm.base.framework.utils.DecimalUtils;
import cn.cmm.base.framework.utils.StringUtils;
import cn.fl.capital.constant.CapitalConstant;
import cn.fl.framework.base.context.CurrentThreadContext;
import cn.fl.framework.constant.DictionaryConstant;
import cn.fl.prjsteprebate.constant.PrjStepRebateFeeConstant;
import cn.fl.prjsteprebate.dto.PrjStepRebateFeeDTO;
import cn.fl.prjsteprebate.dto.PrjStepRebateFeeDetailDTO;
import cn.fl.prjsteprebate.service.IPrjStepRebateApiService;
import cn.fl.prjsteprebate.service.IPrjStepRebateFeeService;
import cn.fl.prjsteprebate.transform.PrjStepRebateFeeVOTransform;
import cn.fl.prjsteprebate.vo.PrjStepRebateFeeDetailVO;
import cn.fl.prjsteprebate.vo.PrjStepRebateFeeVO;
import cn.fl.product.transform.PrjStepRebatePaySchVOTransform;
import cn.fl.product.transform.SplBankVOTransform;
import cn.fl.product.vo.SplBankVO;
import cn.fl.project.api.IPrjPrdMtgApiService;
import cn.fl.project.api.IPrjRbtbillApplyApiService;
import cn.fl.project.condition.PrjStepSchmQueryCondition;
import cn.fl.project.constant.PrjPrdMtgConstant;
import cn.fl.project.constant.PrjQuatPrpsFeeConstant;
import cn.fl.project.dto.PrjPrdMtgDTO;
import cn.fl.project.dto.PrjPrdPaySchDDTO;
import cn.fl.project.dto.PrjStepRebatePaySchDTO;
import cn.fl.project.service.IPrjPrdPaySchDApiService;
import com.alibaba.fastjson.JSON;
import com.shiqiao.fl.creditscore.keyclient.facade.KeyClientApiService;
import fl.spl.facade.spl.api.ISplInfoApiService;
import fl.spl.facade.spl.condition.SplBankQueryCondition;
import fl.spl.facade.splrebates.api.ISplStepRebatesApiService;
import fl.spl.facade.splrebates.dto.SplStepRebatesInfoDTO;
import fl.spl.facade.splrebates.dto.StepRebatesDetailDTO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;


/**
 * @Description: 阶梯返利主表 客户端服务层接口实现
 * @Description: 业务层方法名称前缀：新增：add* 删除：remove* 修改：modify* 查询对象：select* get* 批量：batch* 查询集合：search*
 */
@Service
public class PrjStepRebateFeeServiceImpl implements IPrjStepRebateFeeService {

	/**
	 * 日志
	 */
	private static final Logger logger = LoggerFactory.getLogger(PrjStepRebateFeeServiceImpl.class);
	
	/**
	 * 阶梯返利申请相关接口
	 */
	@Autowired
	private IPrjStepRebateApiService prjStepRebateApiService;
	/**
	 * 供应商相关接口
	 */
	@Autowired
	private ISplInfoApiService splInfoApiService;
	/**
	 * 供应商阶梯返利配置相关接口
	 */
	@Autowired
	private ISplStepRebatesApiService splStepRebatesApiService;
	@Autowired
	private IPrjPrdPaySchDApiService prjPrdPaySchDApiService;
	@Autowired
	private ISysDictionaryApiService sysDictionaryApiService;
	@Autowired
	private ISysOrgApiService sysOrgApiService;
	@Autowired
	private IPrjRbtbillApplyApiService prjRbtbillApplyApiService;
	@Autowired
	private IPrjPrdMtgApiService prjPrdMtgApiService;
	@Autowired
	private KeyClientApiService keyClientApiService;

	@Override
	public PrjStepRebateFeeVO selectById(Long id) throws BaseException{
		if(StringUtils.isEmpty(id)){
			BaseLogUtils.info(logger, "selectById", "主键参数不能为空!", CurrentThreadContext.getCurrentUserName());
			throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_600, "获取对象主键不能为空!");
		}
		PrjStepRebateFeeDTO dto = this.prjStepRebateApiService.selectPrjStepRebateFeeDTOById(id);
		if(dto == null){
			throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_600, "阶梯返利申请记录不存在！");
		}
		List<PrjStepRebateFeeDetailDTO> prjStepRebateFeeDetailDTOS = dto.getPrjStepRebateFeeDetailDTOList();
		for (PrjStepRebateFeeDetailDTO prjStepRebateFeeDetailDTO : prjStepRebateFeeDetailDTOS) {
			SysDictionaryDTO sysDictionaryDTO = sysDictionaryApiService.getEntityByPriKey(CurrentThreadContext.getCurrentSysCd(), CurrentThreadContext.getCurrentOrgCd(), DictionaryConstant.CODE_PRJ_TYPE_CD, prjStepRebateFeeDetailDTO.getPrjTypCd());
			if(sysDictionaryDTO != null){
				prjStepRebateFeeDetailDTO.setPrjTypCdNm(sysDictionaryDTO.getCodeNm());
			}

			//设置组织架构名称
			List<String> buOrgCdList = new ArrayList<>();
			buOrgCdList.add(prjStepRebateFeeDetailDTO.getBuOrgCd());
			SysOrgQueryCondition queryCondition = new SysOrgQueryCondition();
			queryCondition.setSysCd(CurrentThreadContext.getCurrentSysCd());
			queryCondition.setOrgCdList(buOrgCdList);
			List<SysOrgDTO> buOrgList = sysOrgApiService.searchSysOrgList(queryCondition);
			Map<String, String> buOrgMap = new HashMap<>();
			buOrgList.forEach(sysOrgDTO -> {
				if (null != sysOrgDTO && StringUtils.isNotEmpty(sysOrgDTO.getOrgNm())) {
					buOrgMap.put(sysOrgDTO.getOrgCd(), sysOrgDTO.getOrgNm());
				}
			});
			prjStepRebateFeeDetailDTO.setBuOrgCdNm(buOrgMap.get(prjStepRebateFeeDetailDTO.getBuOrgCd()));
			prjStepRebateFeeDetailDTO.setStepRebateAmt(DecimalUtils.convertFenToYuan(prjStepRebateFeeDetailDTO.getStepRebateAmt().longValue()));
			prjStepRebateFeeDetailDTO.setSplBackAmt(DecimalUtils.convertFenToYuan(prjStepRebateFeeDetailDTO.getSplBackAmt().longValue()));
			prjStepRebateFeeDetailDTO.setGpsBackAmt(DecimalUtils.convertFenToYuan(prjStepRebateFeeDetailDTO.getGpsBackAmt().longValue()));
			prjStepRebateFeeDetailDTO.setSalBackAmt(DecimalUtils.convertFenToYuan(prjStepRebateFeeDetailDTO.getSalBackAmt().longValue()));
		}
		dto.setStepRebateAmt(DecimalUtils.convertFenToYuan(dto.getStepRebateAmt().longValue()));
		return PrjStepRebateFeeVOTransform.toVO(dto);
	}

	@Override
	public DataResultDTO add(PrjStepRebateFeeVO entity) throws BaseException{
		if(null == entity){
			BaseLogUtils.info(logger, "add", "新增对象不存在!");
			throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_600,"新增对象不存在!");
		};
		PrjStepRebateFeeDTO prjStepRebateFeeDTO = PrjStepRebateFeeVOTransform.toDTO(entity);
		List<PrjStepRebateFeeDetailDTO> prjStepRebateFeeDetailDTOS = new ArrayList<>();
		//组装返利费用明细列表
		String[] schIds = entity.getPaySchIds().split(",");
		List<Long> paySchIds = new ArrayList<>();
		for (String paySchId : schIds) {
			paySchIds.add(Long.valueOf(paySchId));
		}
		PrjStepSchmQueryCondition prjStepSchmQueryCondition = new PrjStepSchmQueryCondition();
		prjStepSchmQueryCondition.setPaySchIds(paySchIds);
		Pager pager = new Pager();
		pager.setEveryPage(100);
		pager.setCurrentPage(1);
		pager.setCondition(prjStepSchmQueryCondition);
		Pager page = prjStepRebateApiService.searchPrjStepSchmList(pager);
		List<PrjStepRebatePaySchDTO> prjStepRebatePaySchDTOS = (List<PrjStepRebatePaySchDTO>)page.getResultList();
		Integer isBigCstWork = this.checkIsBigCstWork(prjStepRebatePaySchDTOS);
		if(isBigCstWork == 1){
			//REQ-15058 大客户业务发起返利流程需校验该供应商当前逾期情况，逾期90+不得超过1%，
			Map<String,Object> overdue90Result = keyClientApiService.getKeyClientOvd90Open(entity.getSplId());
			String overdue90Code = (String)overdue90Result.get("code");
			if(overdue90Result != null && "200".equals(overdue90Code)){
				Double overdue90Pct = (Double)overdue90Result.get("pct");
				BaseLogUtils.info(logger, "getStepRebateFee", "查询供应商逾期90敞口结果:" + overdue90Pct, CurrentThreadContext.getCurrentUserName());
				if(overdue90Pct != null && DecimalUtils.mul(overdue90Pct,100) >= 1){
					throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_600,"大客户业务逾期敞口超限,不可发起流程!");
				}
			}else{
				String overdue90Msg = (String)overdue90Result.get("msg");
				throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_600,overdue90Msg);
			}
		}
		BaseLogUtils.info(logger, "getStepRebateFee", "查询支付表信息列表返回结果:" + JSON.toJSONString(prjStepRebatePaySchDTOS), CurrentThreadContext.getCurrentUserName());
		//根据splId查询供应商阶梯返利配置信息
		SplStepRebatesInfoDTO splStepRebatesInfoDTO = splStepRebatesApiService.getRebatesRulesBySplId(prjStepRebateFeeDTO.getSplId(),isBigCstWork);
		BaseLogUtils.info(logger, "getStepRebateFee", "查询供应商返利配置返回结果:" + JSON.toJSONString(splStepRebatesInfoDTO), CurrentThreadContext.getCurrentUserName());
		if(splStepRebatesInfoDTO == null || CollectionUtils.isEmpty(splStepRebatesInfoDTO.getDetailDTOList())){
			throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_600,"供应商阶梯返利配置为空!");
		}
		//供应商阶梯返利列表
		List<StepRebatesDetailDTO> stepRebatesDetailDTOS = splStepRebatesInfoDTO.getDetailDTOList();
		//根据供应商查询及参与过计算（申请表状态为已返利）的融资额合计
		List<PrjStepRebatePaySchDTO> prjStepRebatePaySchDTOS1 = prjStepRebateApiService.getPrjStepRebatePaySchBySplId(entity.getSplId());
		double rebatedSchAmt = 0d;
		for (PrjStepRebatePaySchDTO prjStepRebatePaySchDTO : prjStepRebatePaySchDTOS1) {
			if(splStepRebatesInfoDTO.getPrjStarTm().compareTo(prjStepRebatePaySchDTO.getActPayTm()) >= 0 || splStepRebatesInfoDTO.getPrjEndTm().compareTo(prjStepRebatePaySchDTO.getActPayTm()) <= 0){
				continue;
			}
			if(splStepRebatesInfoDTO.getIndateStar().compareTo(prjStepRebatePaySchDTO.getApplyTm()) >= 0 ||splStepRebatesInfoDTO.getIndateEnd().compareTo(prjStepRebatePaySchDTO.getApplyTm()) <= 0){
				continue;
			}
			rebatedSchAmt = rebatedSchAmt + prjStepRebatePaySchDTO.getActLsAmt();
		}
		//this.calculateStartAmt(stepRebatesDetailDTOS);

		//当前选中的支付表总的融资额
		double totalActLsAmt = caculateTotalAmt(prjStepRebatePaySchDTOS);
		double rebateAmtTotal = 0d;
		//取出第一阶梯开始金额 和比例
		//第一阶梯开始
		double firstStartAmt = stepRebatesDetailDTOS.get(0).getStarAmt();
		//第一阶梯比例
		double firstRate = DecimalUtils.div(stepRebatesDetailDTOS.get(0).getRate(),100d);
		if(rebatedSchAmt + totalActLsAmt <= firstStartAmt){
			throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_600,"当前所选总金额不能申请阶梯返利!");
		}
		for (PrjStepRebatePaySchDTO prjStepRebatePaySchDTO : prjStepRebatePaySchDTOS) {
			//放款时间、当前时间是否在有效期校验
			Date now = new Date();
			if(splStepRebatesInfoDTO.getPrjStarTm().compareTo(prjStepRebatePaySchDTO.getActPayTm()) >= 0 || splStepRebatesInfoDTO.getPrjEndTm().compareTo(prjStepRebatePaySchDTO.getActPayTm()) <= 0){
				throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_600,"当前支付表:" +prjStepRebatePaySchDTO.getPaySchNo() +"不在可申请阶梯返利项目范围内!");
			}
			if(splStepRebatesInfoDTO.getIndateStar().compareTo(now) >= 0 ||splStepRebatesInfoDTO.getIndateEnd().compareTo(now) <= 0){
				throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_600,"当前时间不在阶梯返利有效期内!");
			}
			//已申请过阶梯返利且状态为待提交、已返利、返利中校验
			PrjStepRebateFeeDetailDTO prjStepRebateFeeDetailDTOOld = prjStepRebateApiService.selectStepRebateFeeDetail(prjStepRebatePaySchDTO.getPaySchNo());
			if(prjStepRebateFeeDetailDTOOld != null
					&& !prjStepRebateFeeDetailDTOOld.getApplyState().equals(PrjStepRebateFeeConstant.APPLY_STATE_NO_PASS)
					&& !prjStepRebateFeeDetailDTOOld.getApplyState().equals(PrjStepRebateFeeConstant.APPLY_STATE_NO_REBATE)
					&& !prjStepRebateFeeDetailDTOOld.getApplyState().equals(PrjStepRebateFeeConstant.APPLY_TYPE_REBATE)){
				throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_600,"当前支付表:" +prjStepRebatePaySchDTO.getPaySchNo() +"处于供应商返利申请中状态，无法申请阶梯返利!");
			}
			if(prjStepRebateFeeDetailDTOOld != null  && prjStepRebateFeeDetailDTOOld.getApplyState().equals(PrjStepRebateFeeConstant.APPLY_STATE_NO_REBATE)){
				throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_600,"存在不可返利支付表，请核查后再发起流程！");
			}
			//支付表对应项目状态已通过信审审核抵押校验
			Long prjPrdDtlId = prjStepRebatePaySchDTO.getPrjPrdDtlId();
			PrjPrdMtgDTO prjPrdMtgDTO = prjPrdMtgApiService.getPrjPrdMtgByDtlId(prjPrdDtlId);
			if(prjPrdMtgDTO == null || !PrjPrdMtgConstant.CODE_GUAR_STS_CD_MTG.equals(prjPrdMtgDTO.getGuarStsCd())){
				throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_600,"当前支付表:" +prjStepRebatePaySchDTO.getPaySchNo() +"对应项目状态未通过信审审核抵押，无法申请阶梯返利!");
			}
			//是否申请过保险校验 等待接口 周一提供
			String rbtStatus = prjRbtbillApplyApiService.getRbtStatusByPaySchNo(prjStepRebatePaySchDTO.getPaySchNo());
			BaseLogUtils.info(logger, "getStepRebateFee", "查询是否在返利报销流程中:" + rbtStatus, CurrentThreadContext.getCurrentUserName());
			if(!"0".equals(rbtStatus) && !"4".equals(rbtStatus)){
				throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_600,"当前支付表:" +prjStepRebatePaySchDTO.getPaySchNo() +"申请中存在返利报销流程中支付表，无法申请阶梯返利!");
			}
			double actLsAmt = prjStepRebatePaySchDTO.getActLsAmt();
			//当前支付表阶梯返利金额
			double rebateAmt = 0d;
			//供应商返利
			double splBackAmt = 0d;
			//销售返利
			double salBackAmt = 0d;
			//GPS返利
			double gpsBackAmt = 0d;
			//查询费用项
			List<PrjPrdPaySchDDTO> feeList = this.prjPrdPaySchDApiService.searchWSFeeList(prjStepRebatePaySchDTO.getPaySchId());
			for (PrjPrdPaySchDDTO prjPrdPaySchDDTO : feeList) {
				if(PrjQuatPrpsFeeConstant.FEE_TYP_CD_08.equals(prjPrdPaySchDDTO.getFeeTypCd())){
					splBackAmt = splBackAmt + prjPrdPaySchDDTO.getFeeAmt();
				}
				if(PrjQuatPrpsFeeConstant.FEE_TYP_CD_49.equals(prjPrdPaySchDDTO.getFeeTypCd())){
					salBackAmt = salBackAmt + prjPrdPaySchDDTO.getFeeAmt();
				}
				if(PrjQuatPrpsFeeConstant.FEE_TYP_CD_37.equals(prjPrdPaySchDDTO.getFeeTypCd())){
					gpsBackAmt = gpsBackAmt + prjPrdPaySchDDTO.getFeeAmt();
				}
			}
			//如果历史参与过的融资额小于第一阶梯起始金额 且加上本次需要计算的融资额总和 大于第一阶梯起始金额（小于等于的情况上方已给前端提示）
			if(rebatedSchAmt > firstStartAmt){
				rebateAmt =calculateStepRebateAmt(actLsAmt,rebatedSchAmt,stepRebatesDetailDTOS);
			}else{
				//
				if(rebatedSchAmt + actLsAmt <= firstStartAmt){
					rebateAmt = actLsAmt * firstRate;
				}else{
					//参与第一阶梯计算的金额
					double first = firstStartAmt - rebatedSchAmt;
					//超过第一阶梯计算出的返利金额
					double second = calculateStepRebateAmt(actLsAmt-first,rebatedSchAmt+first,stepRebatesDetailDTOS);
					rebateAmt = first * firstRate + second;
				}
			}
			rebateAmt = DecimalUtils.round(rebateAmt,0);
			//计算阶梯返利金额
			//double rebateAmt = this.calculateStepRebateAmt(actLsAmt,rebatedSchAmt,stepRebatesDetailDTOS);
			BaseLogUtils.info(logger, "getStepRebateFee", "计算支付表阶梯返利金额1-支付表号:" + prjStepRebatePaySchDTO.getPaySchNo() + "金额:" + rebateAmt, CurrentThreadContext.getCurrentUserName());

			rebatedSchAmt = rebatedSchAmt + actLsAmt;
			rebateAmtTotal = rebateAmtTotal + rebateAmt;

			//组装阶梯返利明细实体
			PrjStepRebateFeeDetailDTO prjStepRebateFeeDetailDTO = new PrjStepRebateFeeDetailDTO();
			prjStepRebateFeeDetailDTO.setStepRebateAmt(rebateAmt);
			double pct = this.getStepRebateAfterTaxPct();
			prjStepRebateFeeDetailDTO.setAfterTaxStepRebateAmt(DecimalUtils.mul(rebateAmt,pct,0));

			prjStepRebateFeeDetailDTO.setPaySchId(prjStepRebatePaySchDTO.getPaySchId());
			prjStepRebateFeeDetailDTO.setSplBackAmt(splBackAmt);
			prjStepRebateFeeDetailDTO.setSalBackAmt(salBackAmt);
			prjStepRebateFeeDetailDTO.setGpsBackAmt(gpsBackAmt);
			prjStepRebateFeeDetailDTO.setInsCode(prjStepRebatePaySchDTO.getFundRasInsNm());
			prjStepRebateFeeDetailDTO.setBuOrgCd(prjStepRebatePaySchDTO.getBuOrgCd());
			prjStepRebateFeeDetailDTO.setPrjTypCd(prjStepRebatePaySchDTO.getPrjTypCd());
			prjStepRebateFeeDetailDTO.setLsDt(prjStepRebatePaySchDTO.getLsDt());
			prjStepRebateFeeDetailDTOS.add(prjStepRebateFeeDetailDTO);
			prjStepRebateFeeDTO.setBuOrgCd(prjStepRebatePaySchDTO.getBuOrgCd());
		}
		rebateAmtTotal = DecimalUtils.round(rebateAmtTotal,0);
		if(rebateAmtTotal == 0){
			throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_600,"阶梯返利金额为0,不能申请！");
		}
		if(prjStepRebateFeeDTO.getStepRebateAmt() != rebateAmtTotal){
			throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_600,"核对阶梯返利金额不正确!");
		}
		double pct = this.getStepRebateAfterTaxPct();
		prjStepRebateFeeDTO.setAfterTaxStepRebateAmt(DecimalUtils.mul(prjStepRebateFeeDTO.getStepRebateAmt(),pct,0));
		prjStepRebateFeeDTO.setPrjStepRebateFeeDetailDTOList(prjStepRebateFeeDetailDTOS);
		prjStepRebateFeeDTO.setCrtUsrName(CurrentThreadContext.getCurrentUserName());
		prjStepRebateFeeDTO.setOrgCd(CurrentThreadContext.getCurrentOrgCd());
		prjStepRebateFeeDTO.setIsBigCstWork(String.valueOf(isBigCstWork));

		Long id = prjStepRebateApiService.addPrjStepRebateFee(prjStepRebateFeeDTO);
		prjStepRebateFeeDTO.setId(id);
		return prjStepRebateApiService.addPrjStepRebateFeeFlow(prjStepRebateFeeDTO);

	}
	
	/** 
	 * @Description 计算支付表列表融资额总和
	 * @author shenhao  
	 * @date 2020/11/9 16:21
	 * @param   prjStepRebatePaySchDTOS
	 * @return   
	 */ 
	private double caculateTotalAmt(List<PrjStepRebatePaySchDTO> prjStepRebatePaySchDTOS) {
		double totalAmt = 0;
		for (PrjStepRebatePaySchDTO prjStepRebatePaySchDTO : prjStepRebatePaySchDTOS) {
			totalAmt = totalAmt + prjStepRebatePaySchDTO.getActLsAmt();
		}
		return totalAmt;
	}

	@Override
	public boolean removeById(Long id) throws BaseException{
		if(StringUtils.isEmpty(id)){
			BaseLogUtils.info(logger, "removeById", "删除对象主键不能为空!");
			throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_600,"删除对象主键不能为空!");
		};
		//return this.prjStepRebateFeeApiService.removePrjStepRebateFeeDTOById(id);
		//TODO 业务逻辑
		return false;
	}
	
	/**
     * 删除
     * @param ids
     * @return
     */
	@Override
    public boolean removeByIds(List<Long> ids)throws BaseException{
		if(CollectionUtils.isEmpty(ids)){
			BaseLogUtils.info(logger, "removeByIds", "删除主键参数集合不能为空!", CurrentThreadContext.getCurrentUserName());
			throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_600,"删除对象主键不能为空!");
		};
		return false;
    }

	@Override
	public boolean modify(PrjStepRebateFeeVO entity) throws BaseException{
		if(null == entity){
			BaseLogUtils.info(logger, "modify", "修改对象不能为空!");
			throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_600,"修改对象不能为空!");
		};
		return this.prjStepRebateApiService.modifyPrjStepRebateFeeDTO(PrjStepRebateFeeVOTransform.toDTO(entity));
	}

	@Override
	public Pager searchListPage(Pager page) throws BaseException{
		if(null == page){
			page = new Pager();
		}
		//return this.prjStepRebateFeeApiService.searchPrjStepRebateFeeListPage(page);
		//TODO 业务逻辑
		return null;
	}

	@Override
	public List<SplBankVO> getSplBankInfoBySplId(Long splId) throws BaseException {
		if(null==splId){
			return new ArrayList<SplBankVO>();
		}
		SplBankQueryCondition splBankQueryCondition = new SplBankQueryCondition();
		splBankQueryCondition.setSplId(splId);
		splBankQueryCondition.setAudStsCd(CapitalConstant.CODE_SPL_BK_AUD_STS_CD_2);
		return SplBankVOTransform.toVOList(splInfoApiService.searchPrdSplBkList(splBankQueryCondition, CurrentThreadContext.getCurrentSysCd(), CurrentThreadContext.getCurrentOrgCd()));
	}

	@Override
	public PrjStepRebateFeeVO getStepRebateFee(String splId, String paySchs) throws BaseException {
		String[] paySchId = paySchs.split(",");
		List<Long> paySchIds = new ArrayList<>();
		for (String schId : paySchId) {
			paySchIds.add(Long.valueOf(schId));
		}
		PrjStepRebateFeeVO result = new PrjStepRebateFeeVO();
		PrjStepSchmQueryCondition prjStepSchmQueryCondition = new PrjStepSchmQueryCondition();
		prjStepSchmQueryCondition.setPaySchIds(paySchIds);
		Pager pager = new Pager();
		pager.setEveryPage(100);
		pager.setCurrentPage(1);
		pager.setCondition(prjStepSchmQueryCondition);
		Pager page = prjStepRebateApiService.searchPrjStepSchmList(pager);
		List<PrjStepRebatePaySchDTO> prjStepRebatePaySchDTOS = (List<PrjStepRebatePaySchDTO>)page.getResultList();
		Integer isBigCstWork = this.checkIsBigCstWork(prjStepRebatePaySchDTOS);
		//根据splId查询供应商阶梯返利配置信息
		SplStepRebatesInfoDTO splStepRebatesInfoDTO = splStepRebatesApiService.getRebatesRulesBySplId(Long.valueOf(splId),isBigCstWork);
		BaseLogUtils.info(logger, "getStepRebateFee", "查询供应商返利配置返回结果:" + JSON.toJSONString(splStepRebatesInfoDTO), CurrentThreadContext.getCurrentUserName());
		if(splStepRebatesInfoDTO == null || CollectionUtils.isEmpty(splStepRebatesInfoDTO.getDetailDTOList())){
			throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_600,"供应商阶梯返利配置为空!");
		}
		//供应商阶梯返利列表
		List<StepRebatesDetailDTO> stepRebatesDetailDTOS = splStepRebatesInfoDTO.getDetailDTOList();
		//根据供应商查询及参与过计算（申请表状态为已返利）的融资额合计
		List<PrjStepRebatePaySchDTO> prjStepRebatePaySchDTOS1 = prjStepRebateApiService.getPrjStepRebatePaySchBySplId(Long.valueOf(splId));
		double rebatedSchAmt = 0d;
		for (PrjStepRebatePaySchDTO prjStepRebatePaySchDTO : prjStepRebatePaySchDTOS1) {
			if(splStepRebatesInfoDTO.getPrjStarTm().compareTo(prjStepRebatePaySchDTO.getActPayTm()) >= 0 || splStepRebatesInfoDTO.getPrjEndTm().compareTo(prjStepRebatePaySchDTO.getActPayTm()) <= 0){
				continue;
			}
			if(splStepRebatesInfoDTO.getIndateStar().compareTo(prjStepRebatePaySchDTO.getApplyTm()) >= 0 ||splStepRebatesInfoDTO.getIndateEnd().compareTo(prjStepRebatePaySchDTO.getApplyTm()) <= 0){
				continue;
			}
			rebatedSchAmt = rebatedSchAmt + prjStepRebatePaySchDTO.getActLsAmt();
		}
		//this.calculateStartAmt(stepRebatesDetailDTOS);
		BaseLogUtils.info(logger, "getStepRebateFee", "计算当前供应商之前已参与过计算的融资总额1:" + rebatedSchAmt, CurrentThreadContext.getCurrentUserName());
		//当前选中的支付表总的融资额
		double totalActLsAmt = caculateTotalAmt(prjStepRebatePaySchDTOS);
		BaseLogUtils.info(logger, "getStepRebateFee", "计算当前选中的支付表总的融资额:" + totalActLsAmt, CurrentThreadContext.getCurrentUserName());
		double rebateAmtTotal = 0d;
		//取出第一阶梯开始金额 和比例
		//第一阶梯开始
		double firstStartAmt = stepRebatesDetailDTOS.get(0).getStarAmt();
		//第一阶梯比例
		double firstRate = DecimalUtils.div(stepRebatesDetailDTOS.get(0).getRate(),100d);

		for (PrjStepRebatePaySchDTO prjStepRebatePaySchDTO : prjStepRebatePaySchDTOS) {
			BaseLogUtils.info(logger, "getStepRebateFee", "计算当前供应商之前已参与过计算的融资总额2:" + rebatedSchAmt, CurrentThreadContext.getCurrentUserName());
			//当前支付表阶梯返利金额
			double rebateAmt = 0d;
			//放款时间、当前时间是否在有效期校验
			Date now = new Date();
			if(splStepRebatesInfoDTO.getPrjStarTm().compareTo(prjStepRebatePaySchDTO.getActPayTm()) > 0 && splStepRebatesInfoDTO.getPrjEndTm().compareTo(prjStepRebatePaySchDTO.getActPayTm()) < 0){
				throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_600,"当前支付表:" +prjStepRebatePaySchDTO.getPaySchNo() +"不在可申请阶梯返利项目范围内!");
			}
			if(splStepRebatesInfoDTO.getIndateStar().compareTo(now) > 0 && splStepRebatesInfoDTO.getIndateEnd().compareTo(now) < 0){
				throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_600,"当前时间不在阶梯返利有效期内!");
			}
			//已申请过阶梯返利且状态为待提交、已返利、返利中校验
			PrjStepRebateFeeDetailDTO prjStepRebateFeeDetailDTO = prjStepRebateApiService.selectStepRebateFeeDetail(prjStepRebatePaySchDTO.getPaySchNo());
			if(prjStepRebateFeeDetailDTO != null && !prjStepRebateFeeDetailDTO.getApplyState().equals(PrjStepRebateFeeConstant.APPLY_STATE_NO_PASS)
					&& !prjStepRebateFeeDetailDTO.getApplyState().equals(PrjStepRebateFeeConstant.APPLY_STATE_NO_REBATE)
					&& !prjStepRebateFeeDetailDTO.getApplyState().equals(PrjStepRebateFeeConstant.APPLY_STATE_NO_APPLY)){
				throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_600,"当前支付表:" +prjStepRebatePaySchDTO.getPaySchNo() +"处于供应商返利申请中状态，无法申请阶梯返利!");
			}
			//支付表对应项目状态已通过信审审核抵押校验
			Long prjPrdDtlId = prjStepRebatePaySchDTO.getPrjPrdDtlId();
			PrjPrdMtgDTO prjPrdMtgDTO = prjPrdMtgApiService.getPrjPrdMtgByDtlId(prjPrdDtlId);
			if(prjPrdMtgDTO == null || !PrjPrdMtgConstant.CODE_GUAR_STS_CD_MTG.equals(prjPrdMtgDTO.getGuarStsCd())){
				throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_600,"当前支付表:" +prjStepRebatePaySchDTO.getPaySchNo() +"对应项目状态未通过信审审核抵押，无法申请阶梯返利!");
			}
			//是否申请过保险校验 等待接口 周一提供
			String rbtStatus = prjRbtbillApplyApiService.getRbtStatusByPaySchNo(prjStepRebatePaySchDTO.getPaySchNo());
			if(!"0".equals(rbtStatus) && !"4".equals(rbtStatus)){
				throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_600,"当前支付表:" +prjStepRebatePaySchDTO.getPaySchNo() +"申请中存在返利报销流程中支付表，无法申请阶梯返利!");
			}
			if(rebatedSchAmt + totalActLsAmt <= firstStartAmt){
				result.setStepRebateAmt(DecimalUtils.div(rebateAmtTotal,100,2));
				return result;
			}
			double actLsAmt = prjStepRebatePaySchDTO.getActLsAmt();
			//计算阶梯返利金额
			//如果历史参与过的融资额小于第一阶梯起始金额 且加上本次需要计算的融资额总和 大于第一阶梯起始金额（小于等于的情况上方已给前端提示）
			if(rebatedSchAmt > firstStartAmt){
				rebateAmt =calculateStepRebateAmt(actLsAmt,rebatedSchAmt,stepRebatesDetailDTOS);
				BaseLogUtils.info(logger, "getStepRebateFee", "计算支付表阶梯返利金额1-支付表号:" + prjStepRebatePaySchDTO.getPaySchNo() + "金额:" + rebateAmt, CurrentThreadContext.getCurrentUserName());
			}else{
				//
				if(rebatedSchAmt + actLsAmt <= firstStartAmt){
					rebateAmt = actLsAmt * firstRate;
					BaseLogUtils.info(logger, "getStepRebateFee", "计算支付表阶梯返利金额2-支付表号:" + prjStepRebatePaySchDTO.getPaySchNo() + "金额:" + rebateAmt, CurrentThreadContext.getCurrentUserName());
				}else{
					//参与第一阶梯计算的金额
					double first = firstStartAmt - rebatedSchAmt;
					//超过第一阶梯计算出的返利金额
					double second = calculateStepRebateAmt(actLsAmt-first,rebatedSchAmt+first,stepRebatesDetailDTOS);
					rebateAmt = first * firstRate + second;
					BaseLogUtils.info(logger, "getStepRebateFee", "计算支付表阶梯返利金额3-支付表号:" + prjStepRebatePaySchDTO.getPaySchNo() + "金额:" + rebateAmt, CurrentThreadContext.getCurrentUserName());
				}
			}
			rebateAmt = DecimalUtils.round(rebateAmt,0);
			//double rebateAmt = this.calculateStepRebateAmt(actLsAmt,rebatedSchAmt,stepRebatesDetailDTOS);

			rebatedSchAmt = rebatedSchAmt + actLsAmt;
			rebateAmtTotal = rebateAmtTotal + rebateAmt;
		}
		rebateAmtTotal = DecimalUtils.round(rebateAmtTotal,0);
		result.setStepRebateAmt(DecimalUtils.div(rebateAmtTotal,100,2));
		double pct = this.getStepRebateAfterTaxPct();
		result.setAfterTaxStepRebateAmt(DecimalUtils.mul(result.getStepRebateAmt(),pct,2));
		return result;
	}

	/**
	 * @Description 根据阶梯列表查询最先的区间起始
	 * @author shenhao
	 * @date 2020/11/2 10:54
	 * @param
	 * @return
	 */
	private double calculateStartAmt(List<StepRebatesDetailDTO> stepRebatesDetailDTOS) {
		double rebatedSchAmt = 0d;
		for (StepRebatesDetailDTO stepRebatesDetailDTO : stepRebatesDetailDTOS) {
			if(stepRebatesDetailDTO.getStep() == 1){
				rebatedSchAmt = stepRebatesDetailDTO.getStarAmt();
			}
		}
		return rebatedSchAmt;
	}

	/**
	 * @Description (计算阶梯返利金额)
	 * @author shenhao
	 * @date 2020/11/1 13:36
	 * @param
	 * @return
	 */
	private Double calculateStepRebateAmt(double actLsAmt, double rebatedSchAmt, List<StepRebatesDetailDTO> stepRebatesDetailDTOS) {
		double rebateAmt = 0d;
		for (StepRebatesDetailDTO stepRebatesDetailDTO : stepRebatesDetailDTOS) {
			//区间起始金额
			double startAmt = stepRebatesDetailDTO.getStarAmt().doubleValue();
			//区间结束金额
			double endAmt = stepRebatesDetailDTO.getEndAmt().doubleValue();
			//区间返利比例
			double rate = DecimalUtils.div(stepRebatesDetailDTO.getRate(),100d);
			if(rebatedSchAmt >= startAmt && rebatedSchAmt < endAmt){
				//需要参与计算阶梯房里的融资额
				double waitCalculateAmt = 0d;
				if(rebatedSchAmt + actLsAmt <= endAmt){
					waitCalculateAmt = actLsAmt;
					return DecimalUtils.mul(waitCalculateAmt,rate,2);
				}
				if(rebatedSchAmt + actLsAmt > endAmt){
					waitCalculateAmt = endAmt - rebatedSchAmt;
					rebatedSchAmt = rebatedSchAmt + waitCalculateAmt;
					actLsAmt = actLsAmt - waitCalculateAmt;
					return DecimalUtils.add(DecimalUtils.mul(waitCalculateAmt,rate,2),this.calculateStepRebateAmt(actLsAmt,rebatedSchAmt,stepRebatesDetailDTOS));
				}
			}else{
				continue;
			}
		}
		return rebateAmt;
	}

	@Override
	public Pager searchPrjStepSchmList(Pager pager) {
		BaseLogUtils.newLogger("查询支付表列表，查询条件:{}",JSON.toJSONString(pager)).info();
		pager = prjStepRebateApiService.searchPrjStepSchmList(pager);
		BaseLogUtils.newLogger("查询支付表列表，结果:{}",JSON.toJSONString(pager)).info();
		if (CollectionUtils.isEmpty(pager.getResultList())){
			throw new BaseException("查询支付表列表失败");
		}
		pager.setResultList(PrjStepRebatePaySchVOTransform.toVOList((List<PrjStepRebatePaySchDTO>)pager.getResultList()));
		return pager;
	}

	@Override
	public DataResultDTO addPrjStepRebateFeeFlow(PrjStepRebateFeeVO entity) throws BaseException {
		if (null == entity) {
			BaseLogUtils.info(logger, "add", "新增对象不存在!");
			throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_600, "新增对象不存在!");
		}
		PrjStepRebateFeeDTO prjStepRebateFeeDTO = PrjStepRebateFeeVOTransform.toDTO(entity);
		prjStepRebateFeeDTO.setCrtUsrName(CurrentThreadContext.getCurrentUserName());
		return prjStepRebateApiService.addPrjStepRebateFeeFlow(PrjStepRebateFeeVOTransform.toDTO(entity));
	}

	@Override
	public Long applyNoRebate(PrjStepRebateFeeVO entity) throws BaseException {
		if(null == entity){
			BaseLogUtils.info(logger, "add", "新增对象不存在!");
			throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_600,"新增对象不存在!");
		};
		PrjStepRebateFeeDTO prjStepRebateFeeDTO = PrjStepRebateFeeVOTransform.toDTO(entity);
		List<PrjStepRebateFeeDetailDTO> prjStepRebateFeeDetailDTOS = new ArrayList<>();
		//组装返利费用明细列表
		String[] schIds = entity.getPaySchIds().split(",");
		List<Long> paySchIds = new ArrayList<>();
		for (String paySchId : schIds) {
			paySchIds.add(Long.valueOf(paySchId));
		}
		PrjStepSchmQueryCondition prjStepSchmQueryCondition = new PrjStepSchmQueryCondition();
		prjStepSchmQueryCondition.setPaySchIds(paySchIds);
		Pager pager = new Pager();
		pager.setEveryPage(100);
		pager.setCurrentPage(1);
		pager.setCondition(prjStepSchmQueryCondition);
		Pager page = prjStepRebateApiService.searchPrjStepSchmList(pager);
		List<PrjStepRebatePaySchDTO> prjStepRebatePaySchDTOS = (List<PrjStepRebatePaySchDTO>)page.getResultList();
		BaseLogUtils.info(logger, "getStepRebateFee", "查询支付表信息列表返回结果:" + JSON.toJSONString(prjStepRebatePaySchDTOS), CurrentThreadContext.getCurrentUserName());
		Integer isBigCstWork = this.checkIsBigCstWork(prjStepRebatePaySchDTOS);
		for (PrjStepRebatePaySchDTO prjStepRebatePaySchDTO : prjStepRebatePaySchDTOS) {
			PrjStepRebateFeeDetailDTO prjStepRebateFeeDetailDTO = new PrjStepRebateFeeDetailDTO();
			prjStepRebateFeeDetailDTO.setPaySchId(prjStepRebatePaySchDTO.getPaySchId());
			prjStepRebateFeeDetailDTO.setPaySchNo(prjStepRebatePaySchDTO.getPaySchNo());
			//供应商返利
			double splBackAmt = 0d;
			//销售返利
			double salBackAmt = 0d;
			//GPS返利
			double gpsBackAmt = 0d;
			//查询费用项
			List<PrjPrdPaySchDDTO> feeList = this.prjPrdPaySchDApiService.searchWSFeeList(prjStepRebatePaySchDTO.getPaySchId());
			for (PrjPrdPaySchDDTO prjPrdPaySchDDTO : feeList) {
				if(PrjQuatPrpsFeeConstant.FEE_TYP_CD_08.equals(prjPrdPaySchDDTO.getFeeTypCd())){
					splBackAmt = splBackAmt + prjPrdPaySchDDTO.getFeeAmt();
				}
				if(PrjQuatPrpsFeeConstant.FEE_TYP_CD_49.equals(prjPrdPaySchDDTO.getFeeTypCd())){
					salBackAmt = salBackAmt + prjPrdPaySchDDTO.getFeeAmt();
				}
				if(PrjQuatPrpsFeeConstant.FEE_TYP_CD_37.equals(prjPrdPaySchDDTO.getFeeTypCd())){
					gpsBackAmt = gpsBackAmt + prjPrdPaySchDDTO.getFeeAmt();
				}
			}
			prjStepRebateFeeDetailDTO.setSplBackAmt(splBackAmt);
			prjStepRebateFeeDetailDTO.setSalBackAmt(salBackAmt);
			prjStepRebateFeeDetailDTO.setGpsBackAmt(gpsBackAmt);
			prjStepRebateFeeDetailDTO.setInsCode(prjStepRebatePaySchDTO.getFundRasInsNm());
			prjStepRebateFeeDetailDTO.setBuOrgCd(prjStepRebatePaySchDTO.getBuOrgCd());
			prjStepRebateFeeDetailDTO.setPrjTypCd(prjStepRebatePaySchDTO.getPrjTypCd());
			prjStepRebateFeeDetailDTO.setLsDt(prjStepRebatePaySchDTO.getLsDt());
			prjStepRebateFeeDetailDTOS.add(prjStepRebateFeeDetailDTO);
			prjStepRebateFeeDTO.setBuOrgCd(prjStepRebatePaySchDTO.getBuOrgCd());
		}
		prjStepRebateFeeDTO.setIsBigCstWork(String.valueOf(isBigCstWork));
		double pct = this.getStepRebateAfterTaxPct();
		prjStepRebateFeeDTO.setAfterTaxStepRebateAmt(DecimalUtils.mul(prjStepRebateFeeDTO.getStepRebateAmt(),pct,0));
		prjStepRebateFeeDTO.setPrjStepRebateFeeDetailDTOList(prjStepRebateFeeDetailDTOS);
		prjStepRebateFeeDTO.setCrtUsrName(CurrentThreadContext.getCurrentUserName());
		prjStepRebateFeeDTO.setOrgCd(CurrentThreadContext.getCurrentOrgCd());
		return prjStepRebateApiService.applyNoRebate(prjStepRebateFeeDTO);
	}

	private double getStepRebateAfterTaxPct() {
		SysDictionaryDTO sysDictionaryDTO = sysDictionaryApiService.getEntityByPriKey("11000", "0000", DictionaryConstant.CODE_STEP_REBATE_AFTER_TAX_PCT, "StepRebateAfterTaxPct");
		return Double.parseDouble(sysDictionaryDTO.getCodeAttr1());
	}

	@Override
	public boolean cancleNoRebate(String paySchIds) throws BaseException {
		return prjStepRebateApiService.cancleNoRebate(paySchIds);
	}

	private Integer checkIsBigCstWork(List<PrjStepRebatePaySchDTO> prjStepRebatePaySchDTOS) {
		boolean IsHaveBigCstWork = false;
		boolean IsHaveNonBigCstWork = false;
		Integer isBigCstWork = null;
		for (PrjStepRebatePaySchDTO prjStepRebatePaySchDTO : prjStepRebatePaySchDTOS) {
			if(prjStepRebatePaySchDTO.getIsBigCstWork() == 1){
				IsHaveBigCstWork = true;
			}else{
				IsHaveNonBigCstWork = true;
			}
			isBigCstWork = prjStepRebatePaySchDTO.getIsBigCstWork();
		}
		//如果既有大客户业务 又有非大客户业务 提示不可同时发起
		if(IsHaveBigCstWork && IsHaveNonBigCstWork){
			throw new BaseException("大客户业务与非大客户业务不能同时发起！");
		}
		return isBigCstWork;
	}
}
